﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;

namespace Flagwind.Data
{
	public static class EntityExtension
	{
		public static DataTable ToDataTable<Entity>(this IEnumerable<IEntity> source) where Entity : class, IEntity
		{
			if(source == null)
			{
				throw new ArgumentException("参数错误，不能为空!");
			}
			if(!source.Any())
			{
				return null;
			}
			var entities = source.ToList();
			IEntity entity = entities[0];
			string mappingName = entity.GetMappingName() == null ? "Table1" : entity.GetSchemeTableName();
			DataTable dataTable = new DataTable(mappingName);
			foreach(string str in entity.GetPropertyNames())
			{
				var column = new DataColumn(str);
				var value = entity.GetPropertyValue(str);
				column.DataType = value == null || value == DBNull.Value ? typeof(string) : value.GetType();
				dataTable.Columns.Add(column);
			}
			foreach(Entity item in entities)
			{
				dataTable.Rows.Add(item.GetPropertyValues());
			}
			return dataTable;
		}

		public static T GetParent<T>(this IEntity entity) where T : class, IEntity, new()
		{
			return entity.GetParent<T>(DataProviderFactory.DefaultProvider);
		}

		public static T GetParent<T>(this IEntity entity, IDataProvider provider) where T : class, IEntity, new()
		{
			T parent = new T();
			if(parent.GetPrimaryKey().Count == 0)
			{
				return null;
			}
			string foreignKey = entity.GetForeignKey<T>();
			if(string.IsNullOrEmpty(foreignKey) || entity[foreignKey] == null)
			{
				return null;
			}
			try
			{
				parent[parent.GetPrimaryKey()[0]] = entity[foreignKey];
				DataAccess<T> dataAccess = new DataAccess<T>(provider);
				if(dataAccess.Fill(parent))
				{
					return parent;
				}
				else
				{
					Command command = new Command(parent);
					return DataAccess<T>.Instance.Find(command);
				}
			}
			catch(Exception ex)
			{
				throw ex;
			}
		}

		public static IEnumerable<T> GetChildren<T, ParentType>(this IEntity entity) where T : class, IEntity, new() where ParentType : class, IEntity, new()
		{
			return entity.GetChildren<T, ParentType>(DataProviderFactory.DefaultProvider);
		}

		public static IEnumerable<T> GetChildren<T, ParentType>(this IEntity entity, IDataProvider provider) where T : class, IEntity, new() where ParentType : class, IEntity, new()
		{
			T child = new T();
			string foreignKey = child.GetForeignKey<ParentType>();
			if(string.IsNullOrEmpty(foreignKey))
			{
				return null;
			}
			var sql = "SELECT * FROM " + child.GetMappingName() + " WHERE " + foreignKey + " IN ({0})";
			var parameterNames = new List<string>();
			var parameters = new List<IDataParameter>();
			var name = provider.ParameterChar + "P0";
			parameterNames.Add(name);
			parameters.Add(provider.GetParameter(name, entity[entity.GetPrimaryKey()[0]]));
			//会有2100个参数的限制问题，下期解决
			string objSql = string.Format(sql, string.Join(",", parameterNames.ToArray()));
			IDataReader reader = provider.ExecuteDataReader(objSql, CommandType.Text, parameters.ToArray());
			//如果字段名跟实体类属性名不一致,下面这样使用会有问题,
			return DataUtility.ResolveEntityList<T>(reader, child.GetMappingName());
		}
	}
}